<?php

/**
 * Albireo Kernel
 *
 * @copyright  Copyright (c) 2010 Albireo Solutions
 * @package    Kernel
 */


namespace KernelModule;

use Nette\Application\Presenter;
use Nette\Environment;
use \Nette\Forms\Form;

use Celebrio\Util\Localization;

use Albireo\MenuGenerator;
use Albireo\Mode;
use \Albireo\Forms\AlbireoForm;

use Celebrio\AccessControl\AclConstants;
use \Celebrio\AccessControl\UserManagement;
use \Celebrio\AccessControl\AlbireoUser;

use \KernelModule\UsersModule\UserException;
use KernelModule\SignModel;
use \KernelModule\UsersModule\RolesModel;


/**
 * Base class for all application presenters.
 *
 * @author     Albireo Solutions
 * @package    Kernel
 */
abstract class BasePresenter extends Presenter
{

    /**
     * Sets the application to the new directory structure. IMPORTANT!
     * @var boolean
     */
    public $oldModuleMode = FALSE;

    /**
     * Sets the layout mode to the new one. IMPORTANT!
     * @var boolean
     */
    public $oldLayoutMode = FALSE;

    /**
     * Child presenter sets this to false if it does not want to have the rights checked
     * @var bool
     */
    protected $check_rights = true;

    /**
     * Always called to check base read rights of the presenter and to set localization
     */
    public function startup() {
        parent::startup();

        // we don't check right in the applications module or error presenters
        if ($this->check_rights) {
            $this->checkRights();
        }

        Localization::setup();
    }

    public function beforeRender() {
        parent::beforeRender();

        // set localization
        Localization::setTranslator($this->template);

    }

    /**
     * Check access rights for currently accessed resource and privilege
     * (presenter name and view). When the user is not allowed
     *
     * Kernel:SignIn and Kernel:SignOut is accessible by all users, see KernelAcl for details.
     */
    private function checkRights() {
        if ((!Mode::isCritical()) && $this->getUser()->isInRole(AclConstants::ROOT_ROLE)) {
            $this->logoutWithMessage(_("System is no more in critical mode. Please sign in."));
        }
        try {
            //\Logger::getRootLogger()->debug($this->getUser());

            if (!$this->getUser()->isAllowed($this->presenter->name, $this->presenter->view)) {
                $this->flashMessage(_("Not enough rights to display this module!"));
                $this->redirect(":Kernel:SignIn:");
            }
        } catch(\InvalidStateException $e) {
            // InvalidStateException means that something went wrong while 
            // checking permissions in the database. Typicaly, the DB
            // is inaccessible. We should logout user and redirect to SignIn,
            // which also switch view to the critical mode. However, if the
            // mode is not critical, there is another error and we raise 500.
            if (!Mode::isCritical()) {
                throw $e;
            } else {
                // Role 'admin' does not exists usually means the DB connection
                // has screwed up. If not, I'm very sorry for the confusion.
                if ($e->getMessage() === "Role 'admin' does not exist.") {
                    $this->logoutWithMessage(_("The database connection has (probably) been broken."));
                } else {
                    $this->logoutWithMessage(_("Something went terribly wrong: \n") . $e->getMessage() . '\n' . Mode::getMessage());
                }
                
            }
        }
    }
    
    private function logoutWithMessage($message) {
        $sm = new SignModel();
        $sm->signOut($this->getUser(), TRUE);
        $this->flashMessage($message);
        $this->redirect(":Kernel:SignIn:");
    }

    /**
     * Shows main kernel menu
     */
    protected function showMenu() {
        $items = array(
            "Kernel:Overview" => _("Overview"),
            'Kernel:Logs:Overview' => _("Logs"),
            'Kernel:Modules:ModulesManagement' => _("Modules"),
            'Kernel:Users:Overview' => _("Users"),
            'Kernel:Acl:Overview' => _("Security"),
            'Kernel:Applications:Management' => _("Applications")
        );
        if (Environment::getUser()->isLoggedIn()) $items["Kernel:SignOut"] = _("Sign out");
        $permited = (MenuGenerator::generateMainMenu($this->getUser(), "default", $items));

        $this->template->links = $permited;
    }

}